#include<bits/stdc++.h>
using namespace std;
int read(){
    char c=getchar();int x=0,f=1;
    while(!isdigit(c)&&c!='-') c=getchar();
    if(c=='-') f=-1;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)){
        x=x*10+c-'0';
        c=getchar();
    }
    return f*x;
} 
const int N=1e5+20,INF=1e9;
const double EPS=0.0001;
int T,n,m,L,V,d[N],v[N],a[N],p[N];
double lx[N],rx[N];
struct node{
    int ll,rr;
};
node k[N];
int gethj(double x){
    int l=1,r=m,s=0;
    if(x==-1) return -1;
    while(l<=r){
        int mid=(l+r)>>1;
        if(double(p[mid])==x){
            s=mid;
            break;
        }
        if(double(p[mid])>x) r=mid-1,s=mid;
        else l=mid+1;
    }
    return s;
}
int getqq(double x){
    int l=1,r=m,s=0;
    if(x==-1) return -1;
    while(l<=r){
        int mid=(l+r)>>1;
        if(double(p[mid])==x){
            s=mid;
            break;
        }
        if(double(p[mid])>x) r=mid-1;
        else s=mid,l=mid+1;
    }
    return s;
}
bool cmp(node x1,node x2){
    //if(x1.rr==x2.rr) return x1.ll<x2.;
    return x1.rr<x2.rr;
}
int ans=0,pmax,pmin;
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    T=read();
    while(T--){
        // remember to clear
        memset(lx,-1,sizeof(lx));
        memset(rx,-1,sizeof(rx));
        ans=0;pmax=0;pmin=INF;pmax=0;
        n=read();m=read();L=read();V=read();
        for(int i=1;i<=n;i++)  d[i]=read(),v[i]=read(),a[i]=read();
        for(int i=1;i<=m;i++) p[i]=read(),pmax=max(pmax,p[i]),pmin=min(pmin,p[i]); 
        for(int i=1;i<=n;i++){
            if(a[i]<0){
                if(v[i]>V&&d[i]<=pmax){
                    lx[i]=d[i];
                    rx[i]=min(d[i]+(double(v[i]*v[i]-V*V)/double(2*abs(a[i])))-EPS,double(L));
                    //printf("%.6lf\n",rx[i]);
                }
            }
            else if(a[i]==0){
                if(v[i]>V&&d[i]<=pmax){
                    lx[i]=d[i];
                    rx[i]=L;
                }
            }
            else if(a[i]>0){
                if(v[i]>V){
                    lx[i]=d[i];
                    rx[i]=L;
                }
                else if(v[i]==V){
                    lx[i]=d[i]+EPS;
                    rx[i]=L;
                }
                else{
                    lx[i]=d[i]+double(V*V-v[i]*v[i])/double(2*a[i])+EPS;
                    rx[i]=max(lx[i],double(L));
                }
            }
        }
        for(int i=1;i<=n;i++){
            k[i].ll=gethj(lx[i]);
            k[i].rr=getqq(rx[i]);
            if(k[i].ll!=0&&k[i].rr!=0&&k[i].ll!=-1&&k[i].rr!=-1&&k[i].ll<=k[i].rr) ans++;
            if(k[i].ll>k[i].rr) k[i].ll=k[i].rr=-1;
        }
        stable_sort(k+1,k+n+1,cmp);
        //for(int i=1;i<=n;i++) cout<<k[i].ll<<" "<<k[i].rr<<" "<<endl;
        int sum=0,maxr=0;
        for(int i=1;i<=n;i++){
            //cout<<k[i].ll<<" "<<k[i].rr<<endl;
            if(maxr>=m) break;
            if(k[i].ll<=maxr) continue;
            if(k[i].ll>k[i].rr) continue;
            sum++;maxr=k[i].rr;
            //cout<<maxr<<" "<<i<<endl;
        }
        cout<<ans<<" "<<m-sum<<endl;
    }
    return 0;
}
/*
1
5 5 15 3
0 3 0
12 4 0
1 1 4
5 5 -2
6 4 -4
2 5 8 9 15
*/